package com.xfatm.util.typecase;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

/**
 * 类型转换工具类
 * 目前可以转换的类型参照TypeCaseUtils
 */
public class TypeCaseUtils {

    private static TypeCaseUtils typeCaseUtils;
    private static Map<String,Map<String,TypeCase>> typeCaseMap=new HashMap<String, Map<String, TypeCase>>();

    /**
     * 类型转换
     * @param o 需要转换的对象
     * @param clazz 转换成的类型
     * @return 转换后的对象
     */
    public static Object typeCase(Object o,Class<? extends Object> clazz){
        if(o==null){
            if(isBaseType(clazz)){
                return 0;
            }
            return null;
        }
        for(Class<?> c=o.getClass();;c=c.getClass().getSuperclass() ) {
            TypeCase typeCase=TypeCaseUtils.getInstance().getTypeCase(c,clazz);
            if(typeCase!=null){
                return typeCase.typeCase(o);
            }
            if(c==Object.class) {
                break;
            }
        }
        throw new RuntimeException("typecase not found:"+o.getClass().getName()+" to "+clazz.getName());
    }

    /**
     * 注册自定义转换器
     * @param obj 待转换类型
     * @param toObj 转换后的类型
     * @param typeCase 转换器
     */
    public static void registerTypeCase(Class<? extends Object> obj,Class<? extends Object> toObj,TypeCase typeCase){
        TypeCaseUtils.getInstance().register(obj,toObj,typeCase);
    }

    private static TypeCaseUtils getInstance(){
        if(typeCaseUtils==null){
            typeCaseUtils=new TypeCaseUtils();
        }
        return typeCaseUtils;
    }

    private static boolean isBaseType(Class<? extends Object> c){
        return c==byte.class||c==short.class||c==int.class||c==long.class||c==char.class||c==char.class||c==double.class||c==float.class;
    }

    private TypeCaseUtils(){
        ToIntegerTypeCase toIntegerTypeCase=new ToIntegerTypeCase();
        register(Object.class,Integer.class,toIntegerTypeCase.new ObjectToInteger());
        register(Object.class,int.class,toIntegerTypeCase.new ObjectToInt());
        register(BigDecimal.class,int.class,toIntegerTypeCase.new BigDecimalToInt());
        register(BigDecimal.class,Integer.class,toIntegerTypeCase.new BigDecimalToInteger());

        ToStringTypeCase toStringTypeCase=new ToStringTypeCase();
        register(Object.class,String.class,toStringTypeCase.new ObjectToString());

        ToBigDecimalTypeCase toBigDecimalTypeCase=new ToBigDecimalTypeCase();
        register(Object.class,BigDecimal.class,toBigDecimalTypeCase.new ObjectToBigDecimal());

        ToLongTypeCase toLongTypeCase=new ToLongTypeCase();
        register(Object.class,Long.class,toLongTypeCase.new ObjectToLong());
        register(Object.class,long.class,toLongTypeCase.new ObjectToBaseLong());
        register(BigDecimal.class,Long.class,toLongTypeCase.new BigDecimalToLong());
        register(BigDecimal.class,long.class,toLongTypeCase.new BigDecimalToBaseLong());
    }

    private TypeCase getTypeCase(Class<? extends Object> obj,Class<? extends Object> toObj){
        Map<String,TypeCase> map=typeCaseMap.get(obj.getName());
        if(map!=null) {
            return map.get(toObj.getName());
        }
        return null;
    }

    private void register(Class<? extends Object> obj,Class<? extends Object> toObj,TypeCase typeCase) {
        Map<String,TypeCase> map=typeCaseMap.get(obj.getName());
        if(map!=null) {
            map.put(toObj.getName(),typeCase);
        }else {
            map=new HashMap<String, TypeCase>();
            map.put(toObj.getName(),typeCase);
            typeCaseMap.put(obj.getName(),map);
        }
    }




}
